import { Provide, Inject } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, In, Not } from 'typeorm';
import { ClassClassAppointEntity } from '../entity/classAppoint';
import { ClassInfoEntity } from '../entity/info';
import { StudentStudentEntity } from '../../student/entity/student';
import { ClassTrainLogEntity } from '../entity/trainLog';

/**
 * 班级预约
 */
@Provide()
export class ClassClassAppointService extends BaseService {
  @InjectEntityModel(ClassClassAppointEntity)
  classClassAppointEntity: Repository<ClassClassAppointEntity>;

  @InjectEntityModel(ClassInfoEntity)
  classInfoEntity: Repository<ClassInfoEntity>;

  @InjectEntityModel(StudentStudentEntity)
  studentStudentEntity: Repository<StudentStudentEntity>;

  @InjectEntityModel(ClassTrainLogEntity)
  classTrainLogEntity: Repository<ClassTrainLogEntity>;

  @Inject()
  ctx;

  /**
   * 预约班级
   */
  async appointClass(param: {
    studentId: number;  // 学生ID
    classId: number;    // 班级ID
  }) {
    // 检查班级是否存在
    const classInfo = await this.classInfoEntity.findOne({
      where: {
        id: param.classId
      }
    });

    if (!classInfo) {
      throw new CoolCommException('班级不存在');
    }

    // 检查班级人数是否已达上限
    if ((classInfo.currentCount || 0) >= (classInfo.limitCount || 0)) {
      throw new CoolCommException('该班级已达到人数上限，无法预约');
    }

    // 检查学生剩余次数
    const student = await this.studentStudentEntity.findOne({
      where: {
        id: param.studentId
      }
    });

    if (!student) {
      throw new CoolCommException('学生不存在');
    }

    // if ((student.trainCount || 0) <= 0 && (student.giftCount || 0) <= 0) {
    if (student.remainCount <= 0) {
      throw new CoolCommException('训练剩余次数不足，无法预约');
    }

    // 检查是否已经预约过
    const existAppoint = await this.classClassAppointEntity.findOne({
      where: {
        studentId: param.studentId,
        classId: param.classId,
        status: 1
      }
    });

    if (existAppoint) {
      throw new CoolCommException('已经预约过该班级');
    }

    // 创建预约记录
    const appointInfo = new ClassClassAppointEntity();
    appointInfo.studentId = param.studentId;
    appointInfo.classId = param.classId;
    appointInfo.status = 1;
    appointInfo.createTime = new Date();
    appointInfo.updateTime = new Date();

    // 更新班级当前人数
    classInfo.currentCount = (classInfo.currentCount || 0) + 1;
    await this.classInfoEntity.save(classInfo);

    return await this.classClassAppointEntity.save(appointInfo);
  }

  /**
   * 取消预约
   */
  async cancelAppoint(id: number) {
    // 查找预约记录
    const appointInfo = await this.classClassAppointEntity.findOne({
      where: {
        id: id,
        status: 1,
        signStatus: Not(1)  // 排除已签到的预约
      }
    });

    if (!appointInfo) {
      throw new CoolCommException('预约记录已取消或已签到');
    }

    // 更新班级当前人数
    const classInfo = await this.classInfoEntity.findOne({
      where: {
        id: appointInfo.classId
      }
    });

    if (classInfo) {
      classInfo.currentCount = Math.max((classInfo.currentCount || 0) - 1, 0);
      await this.classInfoEntity.save(classInfo);
    }

    // 更新预约状态
    appointInfo.status = 0;
    appointInfo.updateTime = new Date();
    return await this.classClassAppointEntity.save(appointInfo);
  }

  /**
   * 获取班级预约学员列表
   */
  async getClassStudents(classId: number) {
    // 获取班级的所有有效预约记录
    const appointments = await this.classClassAppointEntity.find({
      where: {
        classId: classId,
        status: 1  // 只获取有效预约
      }
    });

    if (!appointments || appointments.length === 0) {
      return [];
    }

    // 获取所有预约学生的ID
    const studentIds = appointments.map(appoint => appoint.studentId);

    // 查询学生信息
    const students = await this.studentStudentEntity.find({
      select: ['id', 'name', 'phone', 'trainCount', 'giftCount', 'buyCount', 'remainCount'],  // 选择需要的字段
      where: {
        id: In(studentIds)
      }
    });
    // 将预约信息和学生信息组合
    const result = students.map(student => {
      const appointment = appointments.find(a => a.studentId === student.id);
      const signStatusText = (() => {
        switch (appointment?.signStatus) {
          case 1:
            return '已签到';
          case 2:
            return '未到';
          default:
            return '-';
        }
      })();

      return {
        student_id: student.id,
        name: student.name,
        phone: student.phone,
        buyCount: student.buyCount,
        remainCount: student.remainCount,
        trainCount: student.trainCount,
        giftCount: student.giftCount,
        signStatus: appointment?.signStatus || 0,
        signStatusText: signStatusText,
        appointId: appointment?.id,
        appointTime: appointment?.createTime
      };
    });

    return result;
  }

  /**
   * 签到
   */
  async signIn(appointId: number) {
    // 查找预约记录
    const appointInfo = await this.classClassAppointEntity.findOne({
      where: {
        id: appointId,
        status: 1  // 只能对有效预约进行签到
      }
    });

    if (!appointInfo) {
      throw new CoolCommException('预约记录不存在');
    }

    if (appointInfo.signStatus === 1) {
      throw new CoolCommException('该预约已签到');
    }

    // 查询学生信息
    const student = await this.studentStudentEntity.findOne({
      where: {
        id: appointInfo.studentId
      }
    });

    if (!student) {
      throw new CoolCommException('学生信息不存在');
    }

    // 检查剩余次数
    // if ((student.trainCount || 0) <= 0 && (student.giftCount || 0) <= 0) {
    if (student.remainCount <= 0) {
      throw new CoolCommException('剩余训练次数不足，无法签到');
    }

    // 记录签到日志
    const trainLog = new ClassTrainLogEntity();
    trainLog.studentId = student.id;
    trainLog.classId = appointInfo.classId;
    trainLog.type = 1;  // 签到类型
    trainLog.count = 0;
    // 优先扣除训练次数，不足则扣除赠送次数
    if ((student.trainCount || 0) > 0) {
      student.remainCount--;
      student.trainCount--;
      trainLog.trainCount = 1;
      trainLog.giftCount = 0;
      trainLog.count++;
    } else {
      student.remainCount--;
      student.giftCount--;
      trainLog.giftCount = 1;
      trainLog.trainCount = 0;
      trainLog.count++;
    }

    // 更新预约状态为已签到
    appointInfo.signStatus = 1;
    appointInfo.updateTime = new Date();

    trainLog.operatorId = this.ctx.admin.userId || 0;
    trainLog.time = new Date();
    trainLog.createTime = new Date();
    trainLog.updateTime = new Date();
    await this.classTrainLogEntity.save(trainLog);

    // 保存更新
    await this.studentStudentEntity.save(student);
    return await this.classClassAppointEntity.save(appointInfo);
  }

}
